{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "github地址:[https://github.com/cheesezh/python_design_patterns](https://github.com/cheesezh/python_design_patterns)\n",
    "\n",
    "## 解释器模式\n",
    "\n",
    "解释器模式，给定一个语言，定一个它的文法的一种表示，并定一个一个解释器，这个解释器使用该表示来解释语言中的橘子。\n",
    "\n",
    "解释其模式需要解决的是，如果一种特定类型的问题发生的频率足够高，那么可能就值得将该问题的各个实例表述为一个简单语言中的橘子。这样就可以构建一个解释器，该解释器通过解释这些橘子来解决该问题。\n",
    "\n",
    "比如说，我们常常会在字符串中搜索匹配的字符或者判断一个字符串是否符合我们的规定格式，此时我们一般会用正则表达式技术。因为匹配字符串的需求在很多地方都会用到，而且行为类似，与其为每一个特定需求都写一个算法函数，不如使用一种通用的搜索算法来解释执行一个正则表达式，该正则表达式定义了待匹配字符串的集合。\n",
    "\n",
    "正则表达式就是解释器模式的一种用用，解释器为正则表达式定义了一个文法，如何表示一个特定的正则表达式，以及如何解释这个正则表达式。\n",
    "\n",
    "解释器模式主要包含以下几个类:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "终结符表达式\n",
      "非终结符表达式\n",
      "终结符表达式\n",
      "非终结符表达式\n"
     ]
    }
   ],
   "source": [
    "from abc import ABCMeta, abstractmethod\n",
    "\n",
    "\n",
    "class AbstractExpression():\n",
    "    \"\"\"\n",
    "    抽象表达式类，声明一个抽象的解释操作，这个接口为抽象语法树中所有的节点所共享\n",
    "    \"\"\"\n",
    "    __metaclass__ = ABCMeta\n",
    "    \n",
    "    @abstractmethod\n",
    "    def interpret(self, context):\n",
    "        pass\n",
    "    \n",
    "\n",
    "class TerminalExpression(AbstractExpression):\n",
    "    \"\"\"\n",
    "    终结符表达式，实现与文法中的终结符相关联的解释操作。实现抽象表达式中所要求的接口，主要是一个interpret()方法。\n",
    "    文法中的每一个终结符都有一个具体终结符表达式与之相对应。\n",
    "    \"\"\"\n",
    "    def interpret(self, context):\n",
    "        print(\"终结符表达式\")\n",
    "        \n",
    "        \n",
    "class NontermialExpression(AbstractExpression):\n",
    "    \"\"\"\n",
    "    非终结符表达式，为文法中的非终结符实现解释操作。对文法中每一条规则R1，R2，...Rn都需要一个具体的非终结符表达式类。\n",
    "    通过实现抽闲表达式的interpret()方法实现解释操作。解释操作以递归的方式调用上 main所提到的代表R1，R2，...Rn中各\n",
    "    个符号的实例变量。\n",
    "    \"\"\"\n",
    "    def interpret(self, context):\n",
    "        print(\"非终结符表达式\")\n",
    "        \n",
    "        \n",
    "class Context():\n",
    "    \"\"\"\n",
    "    上下文类，包含解释器之外的一些全局信息\n",
    "    \"\"\"\n",
    "    def __init__(self):\n",
    "        self.input = None\n",
    "        self.output = None\n",
    "        \n",
    "        \n",
    "def main():\n",
    "    \"\"\"\n",
    "    客户端代码，构建表示该文法定义的语言中一个特定的句子的抽象语法树。\n",
    "    \"\"\"\n",
    "    context = Context()\n",
    "    exp_list = []\n",
    "    exp_list.append(TerminalExpression())\n",
    "    exp_list.append(NontermialExpression())\n",
    "    exp_list.append(TerminalExpression())\n",
    "    exp_list.append(NontermialExpression())\n",
    "    \n",
    "    for exp in exp_list:\n",
    "        exp.interpret(context)\n",
    "        \n",
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 点评\n",
    "\n",
    "当有一个语言需要解释执行，并且你可将该语言中的句子表示为一个抽象语法树时，可使用解释器模式[DP]。\n",
    "\n",
    "用了解释器模式，就意味着可以很容易的改变和扩展文法，因为该模式使用类来表示文法规则，你可以使用继承来改变或扩展该文法。也比较容易实现文法，因为定义抽象语法树中各个节点的类的实现大体类似，这些类都易于直接便携。\n",
    "\n",
    "解释器模式也有不足，解释器模式为文法中每一条规则至少定义了一个类，因此包含许多规则的文法可能难以管理和维护。建议当文法非常复杂时，使用其他技术，如语法分析程序或者编译器生成器来处理[DP]。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
